package edu.gmu.atelier;

import edu.gmu.atelier.generic.RealVector;

/**
 * Matrix implementation with traditional two-dimensional array.
 * @author James H. Pope
 */
public class ArrayMatrix
{
    public double[][] matrix = null;
    
    public ArrayMatrix( double[][] data )
    {
        this.matrix = data;
    }
    
    public int getCols()
    {
        return this.matrix[0].length;
    }
    
    public int getRows()
    {
        return this.matrix.length;
    }
    
    public double[][] getData()
    {
        return this.matrix;
    }
    
    //------------------------------------------------------------------------//
    // Static convenience methods
    //------------------------------------------------------------------------//
    public static RealVector mult(ArrayMatrix m, RealVector x)
    {
        double[] b = new double[m.matrix.length];
        for (int i = 0; i < m.matrix.length; i++)
        {
            for (int j = 0; j < m.matrix[0].length; j++)
            {
                b[i] += m.matrix[i][j] * x.elements[j];
            }
        }
        RealVector bv = new RealVector(b);
        return bv;
    }
    
    public static ArrayMatrix fastMult(ArrayMatrix a, ArrayMatrix b)
    {
        int aRows = a.matrix.length;
        int bCols = b.matrix[0].length;
        int aCols = a.matrix[0].length;
        double[][] c = new double[aRows][bCols];
        for (int i = 0; i < aRows; ++i)
        {
            for (int k = 0; k < aCols; ++k)
            {
                for (int j = 0; j < bCols; ++j)
                {
                    c[i][j] += a.matrix[i][k] * b.matrix[k][j];
                }
            }
        }
        return new ArrayMatrix(c);
    }
    
    public static ArrayMatrix mult(ArrayMatrix a, ArrayMatrix b)
    {
        int aRows = a.matrix.length;
        int bCols = b.matrix[0].length;
        int aCols = a.matrix[0].length;
        double[][] c = new double[aRows][bCols];
        for (int i = 0; i < aRows; ++i)
        {
            for (int j = 0; j < bCols; ++j)
            {
                //double dot = 0;
                for (int k = 0; k < aCols; ++k)
                {
                    c[i][j] += a.matrix[i][k] * b.matrix[k][j];
                }
                //c[i][j] = dot;
            }
        }
        return new ArrayMatrix(c);
    }
    
    //------------------------------------------------------------------------//
    // double[][] utilities
    //------------------------------------------------------------------------//
    public static ArrayMatrix make(double[][] data)
    {
        return new ArrayMatrix( data );
    }
    
    public static double[][] makeCopy(ArrayMatrix a)
    {
        double[][] c = new double[a.matrix.length][a.matrix[0].length];
        for (int i = 0; i < c.length; i++)
        {
            for (int j = 0; j < c[0].length; j++)
            {
                c[i][j] = a.matrix[i][j];
            }
        }
        return c;
    }
}
